#!/usr/bin/python -u
# -*- coding: utf-8 -*-
from __future__ import absolute_import

# -- prioritized --
import sys
import os.path
sys.path.append(os.path.join(os.path.dirname(__file__), './libs'))

# -- stdlib --
import json
import os
import re
import sys
import time

# -- third party --
import gevent

# -- own --

# -- code --
requested = json.loads(sys.stdin.read())
# [{"_metric": "proc.cpu", "name": "redis", "cmdline": "foo!", "interval": 5}]


names = []
cmdlines = []


def find_pid(pattern):
    pids = [i for i in os.listdir('/proc') if i.isdigit()]
    for i in pids:
        try:
            args = open("/proc/%s/cmdline" % i).read().replace('\0', ' ').strip()
            if re.findall(pattern, args):
                return int(i)
        except Exception:
            pass

    return None


def cpu_stat(pid):
    node = open('/proc/stat').read().split('\n')[1].split()[1:]
    node = sum(map(int, node))
    proc = open('/proc/%d/stat' % pid).read().split()
    proc = int(proc[13]) + int(proc[14])
    return node, proc


def monitor_pid(pid, interval):
    node, proc = cpu_stat(pid)
    while True:
        gevent.sleep(interval)
        n1, p1 = cpu_stat(pid)
        if p1 == proc:
            yield 0.0
            continue
        usage = 100.0 * (p1 - proc) / (n1 - node)
        yield usage
        node, proc = n1, p1


def monitor(name, cmdline, interval):
    while True:
        try:
            pid = find_pid(cmdline)
            1 / pid  # throw Exception
            for usage in monitor_pid(pid, interval):
                print json.dumps([{
                    "metric": "proc.cpu",
                    "timestamp": int(time.time()),
                    "step": interval,
                    "tags": {"name": name},
                    "value": usage,
                }])
        except Exception:
            gevent.sleep(1)
            continue


for p in requested:
    assert p["_metric"] == "proc.cpu"
    step = int(p["_step"])
    assert step == 0
    assert 'cmdline' in p
    assert 'name' in p
    gevent.spawn(monitor, p['name'], p['cmdline'], p['interval'])

gevent.hub.get_hub().join()
